unit Hook;

interface
uses
  Windows, SysUtils;
type
  far_jmp =
  packed record
    PuhsOp: byte;
    PushArg: pointer;
    RetOp: byte;
  end;
  Old_Code =
  packed record
    One: Cardinal;
    two: word;
  end;

  phook = record
    Addr: Pointer;
    Jmp: far_jmp;
    Old: Old_Code;
    Your_Func: Pointer;
  end;

function Hook_Function(const ModuleName: string; const functionName: String; const YourFunc: Pointer): Phook;
procedure Unhook_function(const val: Phook);
implementation
var
   bts: Cardinal;

function Hook_Function(const ModuleName: string; const functionName: String; const YourFunc: Pointer): Phook;
var
  res: Phook;

begin
  with res do
  begin
    Addr := GetProcAddress(GetModuleHandle(Pchar(ModuleName)), pchar(functionName)); // nil if non exist
    Jmp.PuhsOp := $68;
    Jmp.PushArg := YourFunc;
    Jmp.RetOp := $C3;
    ReadProcessMemory(GetCurrentProcess, Addr, @Old, sizeof(Old_Code), bts);
    WriteProcessMemory(GetCurrentProcess, Addr, @Jmp, sizeof(far_jmp), bts);
  end;
  Hook_Function := res;
end;

procedure Unhook_function(const val: Phook);
begin
  WriteProcessMemory(GetCurrentProcess, val.Addr, @val.Old, sizeof(Old_Code), bts);
end;

end.
